﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ionic.Zip;
using System.Xml.XPath;
using System.Xml;

//由 Ornithopter 编写  yhd4711499@live.com

namespace Manifest
{
    class ManifestHelper
    {
        static public XmlDocument GetDocumentFromPath(string path)
        {
            XmlDocument document = new XmlDocument();
            document.Load(path);
            return document;
        }

        static public void CreateAttributeInApp(XmlDocument document, string attributeName, string value)
        {
            try
            {
                XPathNavigator navigator = document.CreateNavigator().SelectSingleNode("//App");
                navigator.CreateAttribute(string.Empty, attributeName, string.Empty, value);
            }
            catch (Exception)
            {

            }
        }

        static public void CreateAttribueAnyWhereUnderApp(XmlDocument document, string nodePath, string attributeName, string value)
        {
            try
            {
                XPathNavigator navigator = document.CreateNavigator().SelectSingleNode("//App");
                foreach (string nodeName in nodePath.Split('/'))
                {
                    navigator.MoveToChild(nodeName, string.Empty);
                }
                navigator.CreateAttribute(string.Empty, attributeName, string.Empty, value);
            }
            catch (Exception)
            {
                
            }
        }

        static public void DeleteAttribueAnyWhereUnderApp(XmlDocument document, string nodePath, string attributeName)
        {
            XmlNode xn = GetNodeUnderApp(document, nodePath);
            XmlElement xe = (XmlElement)xn;
            if (xe.HasAttribute(attributeName))
            {
                xe.RemoveAttribute(attributeName);
            }
        }

        static public void CreateAttributeInTask(XmlDocument document, string attributeName, string value)
        {
            XPathNavigator navigator = document.CreateNavigator().SelectSingleNode("//App");
            navigator.MoveToChild("Tasks", string.Empty);
            navigator.MoveToChild("DefaultTask", string.Empty);
            navigator.CreateAttribute(string.Empty, attributeName, string.Empty, value);
        }

        static public XmlNode GetNodeUnderApp(XmlDocument document, string nodePath)
        {
            XmlNode targetNode = document.SelectSingleNode("//App");
            string[] nodePaths = nodePath.Split('/');
            for (int i = 0; i < nodePaths.Length; i++)
            {
                foreach (XmlNode node in targetNode.ChildNodes)
                {
                    if (node.Name == nodePaths[i])
                    {
                        targetNode = node;
                        break;
                    }
                }
            }
            return targetNode;
        }

        static public XmlAttribute GetAttributeUnderNode(XmlDocument document, string nodePath,string attributeName)
        {
            XmlNode targetNode = GetNodeUnderApp(document, nodePath);
            XmlAttribute targetAttribute = null;

            if (targetNode!=null)
            {
                foreach (XmlAttribute attribute in targetNode.Attributes)
                {
                    if (attribute.Name==attributeName)
                    {
                        targetAttribute = attribute;
                        break;
                    }
                }
            }

            return targetAttribute;
        }

        static public void ChangeAttributeValue(XmlDocument document, string nodePath, string attributeName,string value)
        {
            try
            {
                XmlAttribute targetAttribute = GetAttributeUnderNode(document, nodePath, attributeName);
                targetAttribute.Value = value;
            }
            catch (Exception)
            {
                
            }
        }

        static public void ChangNodeValue(XmlDocument document, string nodeXPath,string value)
        {
            XPathNavigator navigator = document.CreateNavigator().SelectSingleNode(nodeXPath);
            navigator.SetValue(value);
        }

        static public bool IsAttributeEqulValue(XmlDocument document, string nodePath,string attributeName, string value)
        {
            XmlAttribute targetAttribute=GetAttributeUnderNode(document,nodePath,attributeName);
            bool result = false;
            if (targetAttribute!=null)
            {
                if (targetAttribute.Value == value)
                {
                    result = true; 
                }
            }
            return result;
        }
    }

    class NavigatorHelper
    {
        static public void MoveNavigatorToPath(XPathNavigator navigator,string path)
        {
            //将路径分割为单独的节点名称，保存在nodesName中
            string[] nodesName = path.Split('/');

            //将指针指到最深的节点处，index--则向浅层移动，index++则向深层移动
            int index = nodesName.Length-1;

            //是否在路径中发现相关
            bool isFound = false;

            //最深的节点也就是目标节点
            string targetNodeName = nodesName[nodesName.Length - 1];

            while (!isFound)
            {
                //查询：在路径中是否存在和navigator当前所在的节点相同名字的节点
                for (int i = nodesName.Length - 1; i >= 0; i--)
                {
                    //发现则将index设置为nodesName中对应的位置，并将isFound设置为true
                    if (navigator.Name == nodesName[i])
                    {
                        isFound = true;
                        index = i;
                        break;
                    }
                }
                //未发现则将nav上移一层
                if (!isFound)
                {
                    navigator.MoveToParent();
                }
            }

            while (navigator.Name != targetNodeName)
            {
                try
                {
                    //将指针往深层移动
                    if (navigator.MoveToChild(nodesName[index + 1], string.Empty))
                        index++;
                    else
                    {
                        if (nodesName[index + 1].Contains("TemplateType"))
                        {
                            nodesName[index + 1] = "TemplateType6";
                        }

                        navigator.MoveToChild(nodesName[index + 1], string.Empty);
                        index++;
                    }
                }
                catch
                {
                    
                }  
            }
        }

        static public void MoveNavigatorToPath(XPathNavigator navigator, string path,string alterpath)
        {
            //将路径分割为单独的节点名称，保存在nodesName中
            string[] nodesName = path.Split('/');
            string[] alterNodesName;

            //将指针指到最深的节点处，index--则向浅层移动，index++则向深层移动
            int index = nodesName.Length - 1;

            //是否在路径中发现相关
            bool isFound = false;

            //最深的节点也就是目标节点
            string targetNodeName = nodesName[nodesName.Length - 1];

            while (!isFound)
            {
                //查询：在路径中是否存在和navigator当前所在的节点相同名字的节点
                for (int i = nodesName.Length - 1; i >= 0; i--)
                {
                    //发现则将index设置为nodesName中对应的位置，并将isFound设置为true
                    if (navigator.Name == nodesName[i])
                    {
                        isFound = true;
                        index = i;
                        break;
                    }
                }
                //未发现则将nav上移一层
                if (!isFound)
                {
                    navigator.MoveToParent();
                }
            }

            while (navigator.Name != targetNodeName)
            {
                try
                {
                    //将指针往深层移动
                    if (navigator.MoveToChild(nodesName[index + 1], string.Empty))
                        index++;
                    else
                    {
                        alterNodesName = alterpath.Split('/');
                        navigator.MoveToChild(alterNodesName[index + 1], string.Empty);
                        index++;
                    }
                }
                catch
                {

                }
            }
        }
    }
}
